﻿/*=====================================================================
  
    File:      TabularDatabase.Table.cs

    Summary:   This is the class that implements all related functionality 
               around Tables in a tabular model, for all TabularDatabase 
               commandlets.
               Functionality for children objects (like columns, measures, 
               etc.) is implemented in separate classes.
 
               This file also contains the definition of the snapin constructor. 
               
 
               Tabular Database Cmdlets (TabularDatabaseCmdlets) is sample code 
               to show and explain how to use the AMO to Tabular (AMO2Tabular)
               library to build a PowerShell library of cmdlets to manage 
               Tabular model objects. 
               The sample can be seen as a sample library of cmdlets
               with the necessary code to execute each particular 
               action or operation over a logical tabular object. 

    Authors:   JuanPablo Jofre (jpjofre@microsoft.com)
    Date:	   04-Apr-2012
  
    Change history:

    @TODO: 
  
-----------------------------------------------------------------------
  
    This file is part of the Microsoft SQL Server Code Samples.
    Copyright (C) Microsoft Corporation.  All rights reserved.
  
  This source code is intended only as a supplement to Microsoft
  Development Tools and/or on-line documentation.  
  
  THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF 
  ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO 
  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  PARTICULAR PURPOSE.
  
======================================================================*/


using System;
using System.Globalization;
using System.Management.Automation;     //  Windows PowerShell assembly.
using MicrosoftSql2012Samples.Amo2Tabular;
using MicrosoftSql2012Samples.TabularDatabaseCmdlet.Properties;
using AMO = Microsoft.AnalysisServices;

namespace MicrosoftSql2012Samples.TabularDatabaseCmdlet
{
    [Cmdlet(VerbsCommon.Add, "FirstTableToTabularDatabase")]
    public class AddFirstTableToTabularDatabase : TabularDatabaseBase
    {
        //  Declare mandatory parameters
        [Parameter(Mandatory = true, Position = 2)]
        [ValidateNotNullOrEmpty]
        public string cubeName { get; set; }

        [Parameter(Mandatory = true, Position = 3)]
        [ValidateNotNullOrEmpty]
        public string datasourceTableName { get; set; }

        [Parameter(Mandatory = true, Position = 4)]
        [ValidateNotNullOrEmpty]
        public string tableName { get; set; }


        // Declare optional parameters for the Add-TabularDatabase cmdlet.
        [Parameter]
        public string process { get; set; }

        [Parameter]
        public bool hidden { get; set; }

        [Parameter]
        public string defaultPartitionFilterClause { get; set; }

        [Parameter]
        public string modelDateColumn { get; set; }

        // Overide the ProcessRecord method to add a Tabular Database
        // using the supplied server name and database name 
        protected override void ProcessRecord()
        {
            //  Validate input arguments
            //  -   process string must be a valid AMO process type or empty/null
            AMO.ProcessType? processType = null;
            if (!process.IsNullOrEmptyOrWhitespace())
            {
                processType = TabularDatabaseHelperFunctions.TryParseProcessType(process);
                if (processType == null)
                    ThrowTerminatingError(new ErrorRecord(new ArgumentException(string.Format(CultureInfo.InvariantCulture, Resources.InvalidProcessValueArgumentException, process)), string.Empty, ErrorCategory.InvalidArgument, null));
            }
            using (AMO.Server server = new AMO.Server())
            {
                try
                {
                    server.Connect(serverName);
                    using (AMO.Database database = server.Databases.GetByName(databaseName))
                    {
                        AMO2Tabular.TableAddFirstTable(database, cubeName, datasourceTableName, tableName, true , processType, !hidden, defaultPartitionFilterClause, modelDateColumn);
                        WriteVerbose(string.Format(CultureInfo.InvariantCulture, Resources.AddTabularFirstTableWriteReport, tableName, databaseName));
                    }
                }
                catch (Exception ex)
                {
                    ThrowTerminatingError(new ErrorRecord(ex, string.Format(CultureInfo.InvariantCulture, Resources.AddTabularFirstTableTerminatingError, databaseName, serverName), ErrorCategory.InvalidOperation, null));
                }
            }

        }

    }

    [Cmdlet(VerbsCommon.Add, "TableToTabularDatabase")]
    public class AddTableToTabularDatabase : TabularDatabaseBase
    {
        //  Declare mandatory parameters
        [Parameter(Mandatory = true, Position = 2)]
        [ValidateNotNullOrEmpty]
        public string datasourceTableName { get; set; }

        [Parameter(Mandatory = true, Position = 3)]
        [ValidateNotNullOrEmpty]
        public string tableName { get; set; }


        // Declare optional parameters for the Add-TabularDatabase cmdlet.
        [Parameter]
        public string process { get; set; }

        [Parameter]
        public bool hidden { get; set; }

        [Parameter]
        public string defaultPartitionFilterClause { get; set; }

        [Parameter]
        public string modelDateColumn { get; set; }

        // Overide the ProcessRecord method to add a Tabular Database
        // using the supplied server name and database name 
        protected override void ProcessRecord()
        {
            //  Validate input arguments
            //  -   process string must be a valid AMO process type
            AMO.ProcessType? processType = TabularDatabaseHelperFunctions.TryParseProcessType(process);
            if (processType == null)
                ThrowTerminatingError(new ErrorRecord(new ArgumentException(string.Format(CultureInfo.InvariantCulture, Resources.InvalidProcessValueArgumentException, process)), string.Empty, ErrorCategory.InvalidArgument, null));

            using (AMO.Server server = new AMO.Server())
            {
                try
                {
                    server.Connect(serverName);
                    using (AMO.Database database = server.Databases.GetByName(databaseName))
                    {
                        AMO2Tabular.TableAdd(database, datasourceTableName, tableName, true, processType, !hidden, defaultPartitionFilterClause, modelDateColumn);
                        WriteVerbose(string.Format(CultureInfo.InvariantCulture, Resources.AddTabularTableWriteReport, tableName, databaseName));
                    }
                }
                catch (Exception ex)
                {
                    ThrowTerminatingError(new ErrorRecord(ex, string.Format(CultureInfo.InvariantCulture, Resources.AddTabularTableTerminatingError, databaseName, serverName), ErrorCategory.InvalidOperation, null));
                }
            }

        }

    }

    [Cmdlet(VerbsCommon.Add, "EmptyTableToTabularDatabase")]
    public class AddEmptyTableToTabularDatabase : TabularDatabaseBase
    {
        //  Declare mandatory parameters
        [Parameter(Mandatory = true, Position = 2)]
        [ValidateNotNullOrEmpty]
        public string datasourceTableName { get; set; }

        [Parameter(Mandatory = true, Position = 3)]
        [ValidateNotNullOrEmpty]
        public string tableName { get; set; }


        // Declare optional parameters for the Add-TabularDatabase cmdlet.
        [Parameter]
        public string defaultPartitionFilterClause { get; set; }


        // Overide the ProcessRecord method to add a Tabular Database
        // using the supplied server name and database name 
        protected override void ProcessRecord()
        {
            //  Validate input arguments

            using (AMO.Server server = new AMO.Server())
            {
                try
                {
                    server.Connect(serverName);
                    using (AMO.Database database = server.Databases.GetByName(databaseName))
                    {
                        AMO2Tabular.TableAddEmptyTable(database, datasourceTableName, tableName, defaultPartitionFilterClause, true);
                        WriteVerbose(string.Format(CultureInfo.InvariantCulture, Resources.AddTabularTableWriteReport, tableName, databaseName));
                    }
                }
                catch (Exception ex)
                {
                    ThrowTerminatingError(new ErrorRecord(ex, string.Format(CultureInfo.InvariantCulture, Resources.AddTabularTableTerminatingError, databaseName, serverName), ErrorCategory.InvalidOperation, null));
                }
            }

        }

    }

    [Cmdlet(VerbsData.Update, "TableProcessInTabularDatabase")]
    public class UpdateTableProcessInTabularDatabase : TabularDatabaseBase
    {

        [Parameter(Mandatory = true, Position = 2)]
        [ValidateNotNullOrEmpty]
        public string tableName { get; set; }

        [Parameter(Mandatory = true, Position = 3)]
        [ValidateNotNullOrEmpty]
        public string process { get; set; }


        // Overide the ProcessRecord method to add a Tabular Database
        // using the supplied server name and database name 
        protected override void ProcessRecord()
        {

            using (AMO.Server server = new AMO.Server())
            {
                //  Validate input arguments
                //  -   process string must be a valid AMO process type 
                AMO.ProcessType? processType = TabularDatabaseHelperFunctions.TryParseProcessType(process);
                if (processType == null)
                    ThrowTerminatingError(new ErrorRecord(new ArgumentException(string.Format(CultureInfo.InvariantCulture, Resources.InvalidProcessValueArgumentException, process)), string.Empty, ErrorCategory.InvalidArgument, null));

                try
                {
                    server.Connect(serverName);
                    using (AMO.Database database = server.Databases.GetByName(databaseName))
                    {
                        AMO2Tabular.TableProcess(database, tableName, processType.Value);
                        WriteVerbose(string.Format(CultureInfo.InvariantCulture, Resources.UpdateTableProcessInTabularDatabaseWriteReport, tableName, databaseName));
                    }
                }
                catch (Exception ex)
                {
                    ThrowTerminatingError(new ErrorRecord(ex, string.Format(CultureInfo.InvariantCulture, Resources.AddTabularTableTerminatingError, databaseName, serverName), ErrorCategory.InvalidOperation, null));
                }
            }

        }

    }

    [Cmdlet(VerbsCommon.Set, "DateTableInTabularDatabase")]
    public class SetDateTableInTabularDatabase : TabularDatabaseBase
    {

        [Parameter(Mandatory = true, Position = 2)]
        [ValidateNotNullOrEmpty]
        public string tableName { get; set; }

        [Parameter(Mandatory = true, Position = 3)]
        [ValidateNotNullOrEmpty]
        public string columnName { get; set; }


        // Overide the ProcessRecord method to add a Tabular Database
        // using the supplied server name and database name 
        protected override void ProcessRecord()
        {
            using (AMO.Server server = new AMO.Server())
            {
                try
                {
                    server.Connect(serverName);
                    using (AMO.Database database = server.Databases.GetByName(databaseName))
                    {
                        AMO2Tabular.TableAlterSetDateTable(database, tableName, columnName, true);
                        WriteVerbose(string.Format(CultureInfo.InvariantCulture, Resources.SetDateTableInTabularDatabaseWriteReport, tableName, databaseName));
                    }
                }
                catch (Exception ex)
                {
                    ThrowTerminatingError(new ErrorRecord(ex, string.Format(CultureInfo.InvariantCulture, Resources.AddTabularTableTerminatingError, databaseName, serverName), ErrorCategory.InvalidOperation, null));
                }
            }

        }

    }

    [Cmdlet(VerbsCommon.Set, "TableVisibilityInTabularDatabase")]
    public class SetTableVisibilityInTabularDatabase : TabularDatabaseBase
    {

        [Parameter(Mandatory = true, Position = 2)]
        [ValidateNotNullOrEmpty]
        public string tableName { get; set; }

        [Parameter(Mandatory = false, Position = 3)]
        public SwitchParameter Visible
        {
            get { return visible; }
            set { visible = value; }
        }
        private bool visible;

        // Overide the ProcessRecord method to add a Tabular Database
        // using the supplied server name and database name 
        protected override void ProcessRecord()
        {
            using (AMO.Server server = new AMO.Server())
            {
                try
                {
                    server.Connect(serverName);
                    using (AMO.Database database = server.Databases.GetByName(databaseName))
                    {
                        AMO2Tabular.TableAlterSetVisibility(database, tableName, visible, true);
                        WriteVerbose(string.Format(CultureInfo.InvariantCulture, Resources.SetTableVisibilityInTabularDatabaseWriteReport, tableName, databaseName));
                    }
                }
                catch (Exception ex)
                {
                    ThrowTerminatingError(new ErrorRecord(ex, string.Format(CultureInfo.InvariantCulture, Resources.AddTabularTableTerminatingError, databaseName, serverName), ErrorCategory.InvalidOperation, null));
                }
            }

        }

    }

    [Cmdlet(VerbsCommon.Get, "TablesInTabularDatabase")]
    public class GetTablesInTabularDatabase : TabularDatabaseBase
    {

        // Overide the ProcessRecord method to Get all Calculated Column names
        // using the supplied server name, database name and table
        protected override void ProcessRecord()
        {

            using (AMO.Server server = new AMO.Server())
            {
                try
                {
                    server.Connect(serverName);
                    using (AMO.Database database = server.Databases.GetByName(databaseName))
                    {
                        foreach (string tableName in AMO2Tabular.TablesEnumerate(database))
                        {
                            WriteObject(tableName, true);
                        }
                    }
                }
                catch (Exception ex)
                {
                    ThrowTerminatingError(new ErrorRecord(ex, string.Format(CultureInfo.InvariantCulture, Resources.AddTabularTableTerminatingError, databaseName, serverName), ErrorCategory.InvalidOperation, null));
                }
            }

        }

    }
}
